﻿// 
//=====================================================================================
// Repository: https://gitee.com/putzone/fofasearch
//=====================================================================================
//
using LitJson;
using System;
using System.Data;
using System.Text;
using System.Web;

namespace FofaLib
{
    public class FofaClient
    {
        const string SearchBaseUrl = "https://fofa.so/api/v1/search/all";

        public string Email = string.Empty;
        public string ApiKey = string.Empty;
        public string Fields = "host";

        public FofaClient()
        {

        }

        public FofaClient(string email, string apiKey, string fields)
        {
            this.Email = email;
            this.ApiKey = apiKey;
            this.Fields = fields;
        }

        public FResult Search(string searchKey, int size)
        {
            FResult fResult = new FResult()
            {
                Error = true
            };
            if (string.IsNullOrEmpty(Email))
            {
                fResult.ErrorMsg = "Email值不正确";
                return fResult;
            }
            if(string.IsNullOrEmpty(ApiKey))
            {
                fResult.ErrorMsg = "ApiKey值不正确";
                return fResult;
            }
            if (string.IsNullOrEmpty(searchKey))
            {
                fResult.ErrorMsg = "搜索条件不能为空";
                return fResult;
            }
            if (string.IsNullOrEmpty(Fields))
            {
                KeyMapping keyMapping = new KeyMapping();
                foreach (string col in keyMapping.Header.Keys)
                {
                    Fields += col + ",";
                }
            }
            Fields = Fields.Replace(" ", "");
            Fields = Fields.TrimEnd(',');

            string searchUrl = string.Format("{0}?email={1}&key={2}&qbase64={3}&fields={4}&size={5}", SearchBaseUrl, Email, ApiKey, HttpUtility.UrlEncode(Convert.ToBase64String(Encoding.UTF8.GetBytes(searchKey))), Fields, size);
            fResult.SearchUrl = searchUrl;
            HttpResult httpResult = HttpHelper.Get(searchUrl);
            if (httpResult.Error)
            {
                fResult.ErrorMsg = httpResult.Result;
                return fResult;
            }
            string rawContent = httpResult.Result;
            if (rawContent.IndexOf("\"error\":") == -1)
            {
                fResult.ErrorMsg = "Fofa服务器返回数据异常";
                return fResult;
            }
            JsonData content = JsonMapper.ToObject(rawContent);
            if ((bool)content["error"])
            {
                if (content.ContainsKey("errmsg"))
                {
                    string errmsg = content["errmsg"].ToString();
                    if (errmsg.Contains("401 Unauthorized"))
                    {
                        fResult.ErrorMsg = "未授权 " + errmsg;
                    }
                    else if (errmsg.Contains("query statement error"))
                    {
                        fResult.ErrorMsg = "查询语法错误 " + errmsg;
                    }
                    else
                    {
                        fResult.ErrorMsg = errmsg;
                    }
                }
                else
                {
                    fResult.ErrorMsg = "Fofa服务器返回错误提示";
                }
                return fResult;
            }
            fResult.Size = (int)content["size"];
            if (fResult.Size == 0)
            {
                fResult.ErrorMsg = "没有查询到数据";
                return fResult;
            }
            if (!Fields.Contains(","))
            {
                fResult.ResultSet.Columns.Add(Fields);
            }
            else
            {
                foreach(string col in Fields.Split(','))
                {
                    KeyMapping keyMapping = new KeyMapping();
                    string colName = col;
                    if (keyMapping.Header.ContainsKey(colName))
                    {
                        colName = keyMapping.Header[col].ToString();
                    }
                    fResult.ResultSet.Columns.Add(colName);
                }
            }
            foreach (JsonData result in content["results"])
            {
                DataRow row = fResult.ResultSet.NewRow();
                if (fResult.ResultSet.Columns.Count == 1)
                {
                    row[0] = result;
                }
                else
                {
                    for (int n = 0; n < Fields.Split(',').Length; n++)
                    {
                        row[n] = result[n];
                    }
                }
                fResult.ResultSet.Rows.Add(row);
            }
            fResult.Error = false;
            return fResult;
        }

    }
}
